home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: DZDisplay.c
- * Author: Dan Venolia
- *
- * Contents: Handles the window and its contents.
- *
- * Copyright © 1996 Apple Computer, Inc.
- */
-
- #ifndef USE_DRAW_SPROCKET
- #define USE_DRAW_SPROCKET 1
- #endif
-
- #include <assert.h>
-
- #include <Windows.h>
-
- #include <QD3D.h>
- #include <QD3DCamera.h>
- #include <QD3DDrawContext.h>
- #include <QD3DGroup.h>
- #include <QD3DLight.h>
- #include <QD3DMath.h>
- #include <QD3DRenderer.h>
- #include <QD3DShader.h>
- #include <QD3DView.h>
-
- #include "DZDisplay.h"
- #include "DZGame.h"
- #include "DZResource.h"
-
- #if USE_DRAW_SPROCKET
- #include "DrawSprocket.h"
- #endif
-
-
- #if USE_DRAW_SPROCKET
- static DisplayObject gDisplayObject = NULL;
- #else
- static WindowPtr gDisplayWindow = NULL;
- #endif
-
- static Boolean gDisplayActive = false;
-
- static TQ3ViewObject gDisplayView = NULL;
- static TQ3DrawContextObject gDisplayDrawContext = NULL;
- static TQ3RendererObject gDisplayRenderer = NULL;
- static TQ3CameraObject gDisplayCamera = NULL;
- static TQ3GroupObject gDisplayLightGroup = NULL;
- static TQ3LightObject gDisplayAmbientLight = NULL;
- static TQ3LightObject gDisplayDirectionalLight = NULL;
- static TQ3LightObject gDisplayPointLight = NULL;
- static TQ3ShaderObject gDisplayIllumination = NULL;
-
- //• To get around an Interactive Renderer bug wherein Q3Renderer_Sync
- //• crashes when called on a renderer that has not rendered.
- static Boolean gDisplayHasRendered = false;
-
-
- #if USE_DRAW_SPROCKET
- static Boolean Display_IsBusy(
- DisplayObject inDisplayObject,
- UInt32 inContext);
- #endif
-
- static void Display_GetImageArea(
- TQ3Area* outArea);
-
- static float Display_GetImageAspectRatio(
- void);
-
-
- /* =============================================================================
- * Display_Init (external)
- *
- * Creates the display window, initializes QD3D view etc. to draw in it.
- * ========================================================================== */
- void Display_Init(
- void)
- {
- TQ3ViewAngleAspectCameraData viewAngleCameraData;
- TQ3PointLightData pointLightData;
- TQ3ColorRGB white = {1.0, 1.0, 1.0};
-
- // uncomment the next line and draw sprocket won't make your life miserable when you drop into the debugger
- // LeaveDisplaysVisible( false );
-
- // Create the view
- gDisplayView = Q3View_New();
-
- // Set up where to draw
- #if USE_DRAW_SPROCKET
- {
- DisplayConfig theConfig;
- DisplayConfig theActualConfig;
-
- // Create the display
- theConfig.device = NULL;
- theConfig.mode = 0;
- theConfig.frequency = 0;
- theConfig.width = 512;
- theConfig.height = 384;
- theConfig.colorNeeds = kDisplayColorRequest;
- theConfig.colorTable = NULL;
- theConfig.specialFlags = kDisplaySpecialBuffered | kDisplaySpecialQD3DAccel;
- theConfig.specialFlagsInHW = 0;
- theConfig.frontBufferDepthMask = kDisplayDepthMaskAll;
- theConfig.backBufferDepthMask = kDisplayDepthMask32 | kDisplayDepthMask16;
- theConfig.frontBufferBestDepth = 32;
- theConfig.backBufferBestDepth = 32;
- theConfig.pageCount = 2;
- theConfig.reserved1 = 0;
- theConfig.reserved2 = 0;
- FindGDeviceFromConfig( &theConfig );
- NewDisplay( &theConfig, &gDisplayObject );
-
- GetDisplayActualConfig( gDisplayObject, &theActualConfig );
- if (theActualConfig.frontBufferBestDepth < 16)
- {
- //• SHOULD PUT UP AN ALERT HERE SAYING SOMETHING LIKE
- //• "The best monitor setting that DroneZone could find was XXX."
- //• "DroneZone runs much faster in Thousands or Millions of Colors."
- //• "You can run in Thousands or Millions of Colors if you expand"
- //• "the Video RAM on your display card, or if you switch to a smaller"
- //• "video monitor." (OK) (Quit)
- }
-
- // DSp_SetDebugMode( true );
-
- FadeDisplayGamma( NULL, kSmoothFadeOut, NULL );
- SetDisplayPlayState( gDisplayObject, kDisplayPlayStateActive );
- //• SHOW SPLASH SCREEN HERE
- FadeDisplayGamma( NULL, kSmoothFadeIn, NULL );
-
- #if 1
- {
- GWorldPtr theGWorld;
- PixMapHandle pixMapHandle;
- TQ3PixmapDrawContextData pixmapDrawContextData;
- // Create the draw context
- GetDisplayBackBuffer( gDisplayObject, &theGWorld );
- pixMapHandle = GetGWorldPixMap(theGWorld);
-
- pixmapDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- pixmapDrawContextData.drawContextData.clearImageColor.a = 1.0;
- pixmapDrawContextData.drawContextData.clearImageColor.r = 0.0;
- pixmapDrawContextData.drawContextData.clearImageColor.g = 0.0;
- pixmapDrawContextData.drawContextData.clearImageColor.b = 0.0;
- pixmapDrawContextData.drawContextData.paneState = kQ3False;
- pixmapDrawContextData.drawContextData.maskState = kQ3False;
- pixmapDrawContextData.drawContextData.doubleBufferState = kQ3False;
-
- pixmapDrawContextData.pixmap.image = GetPixBaseAddr(pixMapHandle);
- pixmapDrawContextData.pixmap.width = theConfig.width;
- pixmapDrawContextData.pixmap.height = theConfig.height;
- pixmapDrawContextData.pixmap.rowBytes = (*pixMapHandle)->rowBytes & 0x00003FFF;
- pixmapDrawContextData.pixmap.pixelSize = theActualConfig.frontBufferBestDepth;
- pixmapDrawContextData.pixmap.bitOrder = kQ3EndianBig;
- pixmapDrawContextData.pixmap.byteOrder = kQ3EndianBig;
-
- switch (pixmapDrawContextData.pixmap.pixelSize)
- {
- case 16:
- pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB16;
- break;
-
- case 32:
- pixmapDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB32;
- break;
-
- default:
- assert(0);
- }
-
- gDisplayDrawContext = Q3PixmapDrawContext_New(&pixmapDrawContextData);
- }
- #else
- {
- TQ3MacDrawContextData macDrawContextData;
-
- // Create the draw context
- macDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- macDrawContextData.drawContextData.clearImageColor.a = 1.0;
- macDrawContextData.drawContextData.clearImageColor.r = 0.0;
- macDrawContextData.drawContextData.clearImageColor.g = 0.0;
- macDrawContextData.drawContextData.clearImageColor.b = 0.0;
- macDrawContextData.drawContextData.maskState = kQ3False;
- macDrawContextData.drawContextData.paneState = kQ3False;
- macDrawContextData.drawContextData.doubleBufferState = kQ3False;
- macDrawContextData.library = kQ3Mac2DLibraryNone;
- macDrawContextData.viewPort = NULL;
- macDrawContextData.grafPort = NULL;
-
- GetDisplayBackBuffer( gDisplayObject, &macDrawContextData.window );
-
- gDisplayDrawContext = Q3MacDrawContext_New(&macDrawContextData);
- }
- #endif
- }
- #else
- {
- TQ3MacDrawContextData macDrawContextData;
-
- // Create the window
- gDisplayWindow = GetNewCWindow(kWindID_Display, NULL, (WindowPtr)(-1));
-
- // Create the draw context
- macDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor;
- macDrawContextData.drawContextData.clearImageColor.a = 1.0;
- macDrawContextData.drawContextData.clearImageColor.r = 0.0;
- macDrawContextData.drawContextData.clearImageColor.g = 0.0;
- macDrawContextData.drawContextData.clearImageColor.b = 0.0;
- macDrawContextData.drawContextData.maskState = kQ3False;
- macDrawContextData.library = kQ3Mac2DLibraryNone;
- macDrawContextData.drawContextData.paneState = kQ3True;
- macDrawContextData.drawContextData.doubleBufferState = kQ3True;
- macDrawContextData.window = (CGrafPtr) gDisplayWindow;
-
- Display_GetImageArea(&macDrawContextData.drawContextData.pane);
-
- gDisplayDrawContext = Q3MacDrawContext_New(&macDrawContextData);
- }
- #endif
-
- Q3View_SetDrawContext(gDisplayView, gDisplayDrawContext);
-
- // Create the renderer
- #if 1
- gDisplayRenderer = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
- Q3InteractiveRenderer_SetDoubleBufferBypass(gDisplayRenderer, kQ3True);
- #else
- gDisplayRenderer = Q3Renderer_NewFromType(kQ3RendererTypeWireframe);
- #endif
-
- Q3View_SetRenderer(gDisplayView, gDisplayRenderer);
-
- // Create the camera
- viewAngleCameraData.cameraData.placement.cameraLocation.x = 0.0;
- viewAngleCameraData.cameraData.placement.cameraLocation.y = 0.0;
- viewAngleCameraData.cameraData.placement.cameraLocation.z = 0.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.x = 1.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.y = 0.0;
- viewAngleCameraData.cameraData.placement.pointOfInterest.z = 0.0;
- viewAngleCameraData.cameraData.placement.upVector.x = 0.0;
- viewAngleCameraData.cameraData.placement.upVector.y = 1.0;
- viewAngleCameraData.cameraData.placement.upVector.z = 0.0;
- viewAngleCameraData.cameraData.range.hither = 0.2;
- viewAngleCameraData.cameraData.range.yon = 200.0;
- viewAngleCameraData.cameraData.viewPort.origin.x = -1.0;
- viewAngleCameraData.cameraData.viewPort.origin.y = 1.0;
- viewAngleCameraData.cameraData.viewPort.width = 2.0;
- viewAngleCameraData.cameraData.viewPort.height = 2.0;
- viewAngleCameraData.fov = 1.2;
- viewAngleCameraData.aspectRatioXToY = Display_GetImageAspectRatio();
-
- gDisplayCamera = Q3ViewAngleAspectCamera_New(&viewAngleCameraData);
-
- Q3View_SetCamera(gDisplayView, gDisplayCamera);
-
- // Create the light group
- gDisplayLightGroup = Q3LightGroup_New();
- Q3View_SetLightGroup(gDisplayView, gDisplayLightGroup);
-
- // Create the point light
- pointLightData.lightData.isOn = kQ3True;
- pointLightData.lightData.brightness = 5.0;
- pointLightData.lightData.color = white;
- pointLightData.castsShadows = kQ3True;
- pointLightData.attenuation = kQ3AttenuationTypeInverseDistance;
- pointLightData.location.x = 0.0;
- pointLightData.location.y = 0.0;
- pointLightData.location.z = 0.0;
-
- gDisplayPointLight = Q3PointLight_New(&pointLightData);
-
- Q3Group_AddObject(gDisplayLightGroup, gDisplayPointLight);
-
- // Create the illumination shader
- #if 1
- gDisplayIllumination = Q3PhongIllumination_New();
- #else
- gDisplayIllumination = Q3LambertIllumination_New();
- #endif
- }
-
-
- /* =============================================================================
- * Display_Exit (external)
- *
- * Takes down the window, disposes of the QD3D stuff.
- * ========================================================================== */
- void Display_Exit(
- void)
- {
- if (gDisplayHasRendered)
- {
- Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- }
-
- #if USE_DRAW_SPROCKET
- if( gDisplayObject != NULL )
- {
- FadeDisplayGamma( NULL, kSmoothFadeOut, NULL );
- SetDisplayPlayState( gDisplayObject, kDisplayPlayStateInactive );
- FadeDisplayGamma( NULL, kSmoothFadeIn, NULL );
- DisposeDisplay( gDisplayObject );
- gDisplayObject = NULL;
- }
- #else
- if (gDisplayWindow != NULL)
- {
- DisposeWindow(gDisplayWindow);
- gDisplayWindow = NULL;
- }
- #endif
-
- if (gDisplayView != NULL)
- {
- Q3Object_Dispose(gDisplayView);
- gDisplayView = NULL;
- }
-
- if (gDisplayDrawContext != NULL)
- {
- Q3Object_Dispose(gDisplayDrawContext);
- gDisplayDrawContext = NULL;
- }
-
- if (gDisplayRenderer != NULL)
- {
- Q3Object_Dispose(gDisplayRenderer);
- gDisplayRenderer = NULL;
- }
-
- if (gDisplayCamera != NULL)
- {
- Q3Object_Dispose(gDisplayCamera);
- gDisplayCamera = NULL;
- }
-
- if (gDisplayLightGroup != NULL)
- {
- Q3Object_Dispose(gDisplayLightGroup);
- gDisplayLightGroup = NULL;
- }
-
- if (gDisplayAmbientLight != NULL)
- {
- Q3Object_Dispose(gDisplayAmbientLight);
- gDisplayAmbientLight = NULL;
- }
-
- if (gDisplayDirectionalLight != NULL)
- {
- Q3Object_Dispose(gDisplayDirectionalLight);
- gDisplayDirectionalLight = NULL;
- }
-
- if (gDisplayPointLight != NULL)
- {
- Q3Object_Dispose(gDisplayPointLight);
- gDisplayPointLight = NULL;
- }
-
- if (gDisplayIllumination != NULL)
- {
- Q3Object_Dispose(gDisplayIllumination);
- gDisplayIllumination = NULL;
- }
- }
-
-
- /* =============================================================================
- * Display_Activate (external)
- *
- * Handles activation and deactivation.
- * ========================================================================== */
- void Display_Activate(
- Boolean inActivate)
- {
- if (gDisplayActive != inActivate)
- {
- gDisplayActive = inActivate;
-
- if (gDisplayHasRendered)
- {
- Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- }
-
- Display_DrawGrow();
- }
- }
-
-
- /* =============================================================================
- * Display_IsActive (external)
- *
- * Returns true if the game is active.
- * ========================================================================== */
- Boolean Display_IsActive(
- void)
- {
- #if USE_DRAW_SPROCKET
- return true;
- #else
- return gDisplayActive;
- #endif
- }
-
-
- /* =============================================================================
- * Display_DrawGrow (external)
- *
- * Draws the grow box.
- * ========================================================================== */
- void Display_DrawGrow(
- void)
- {
- #if !USE_DRAW_SPROCKET
- Rect bounds;
-
- SetPort(gDisplayWindow);
-
- // Erase the horizontal part
- bounds = gDisplayWindow->portRect;
- bounds.top = bounds.bottom-15;
-
- EraseRect(&bounds);
-
- // Draw the grow box, but only the horizontal scroll stuff
- ClipRect(&bounds);
- DrawGrowIcon(gDisplayWindow);
- ClipRect(&gDisplayWindow->portRect);
- #endif
- }
-
-
- /* =============================================================================
- * Display_DrawImage (external)
- *
- * Draws the 3D part of the window.
- * ========================================================================== */
- void Display_DrawImage(
- void)
- {
- #if USE_DRAW_SPROCKET
- {
- GWorldPtr theGWorld;
-
- GetDisplayBackBuffer( gDisplayObject, &theGWorld );
- Q3MacDrawContext_SetWindow( gDisplayDrawContext, theGWorld );
- }
- #endif
-
- Q3View_StartRendering(gDisplayView);
- do
- {
- // Set up the rendering state
- Q3InterpolationStyle_Submit(kQ3InterpolationStyleVertex, gDisplayView);
- Q3BackfacingStyle_Submit(kQ3BackfacingStyleFlip, gDisplayView);
- Q3FillStyle_Submit(kQ3FillStyleFilled, gDisplayView);
- Q3Object_Submit(gDisplayIllumination, gDisplayView);
-
- // Draw the game contents
- Game_Submit(gDisplayView);
- }
- while (Q3View_EndRendering(gDisplayView) == kQ3ViewStatusRetraverse);
-
- gDisplayHasRendered = true;
-
- #if USE_DRAW_SPROCKET
- SwapDisplayBuffers( gDisplayObject, Display_IsBusy, 0 );
- #endif
- }
-
-
- /* =============================================================================
- * Display_IsBusy (internal)
- *
- * Called by SwapDisplayBuffers (or a VBL task that it kicks off) to determine
- * if the back buffer is finished rendering. Since QD3D can render
- * asynchronously through hardware, we have to let it finish. Unfortunately,
- * the only way to do this is to hang here with a renderer Sync call.
- * ========================================================================== */
- #if USE_DRAW_SPROCKET
- Boolean Display_IsBusy(
- DisplayObject inDisplayObject,
- UInt32 inContext)
- {
- Q3Renderer_Sync(gDisplayRenderer, gDisplayView);
- return false;
- }
- #endif
-
-
- /* =============================================================================
- * Display_Resize (external)
- *
- * Called after the window has changed size.
- * ========================================================================== */
- void Display_Resize(
- void)
- {
- #if !USE_DRAW_SPROCKET
- TQ3Area imageArea;
-
- // Reset the clip
- ClipRect(&gDisplayWindow->portRect);
-
- // Change the draw context
- Display_GetImageArea(&imageArea);
- Q3DrawContext_SetPane(gDisplayDrawContext, &imageArea);
-
- // Change the camera aspect ratio
- Q3ViewAngleAspectCamera_SetAspectRatio(gDisplayCamera, Display_GetImageAspectRatio());
- #endif
- }
-
-
- /* =============================================================================
- * Display_GetWindow (external)
- *
- * Returns our window pointer.
- * ========================================================================== */
- WindowPtr Display_GetWindow(
- void)
- {
- #if USE_DRAW_SPROCKET
- return NULL;
- #else
- return gDisplayWindow;
- #endif
- }
-
-
- /* =============================================================================
- * Display_SetViewerPosition (external)
- *
- * Moves the camera and point light based on the given info.
- * ========================================================================== */
- void Display_SetViewerPosition(
- const TQ3Point3D* inPosition,
- const TQ3Vector3D* inDirection,
- const TQ3Vector3D* inUp)
- {
- TQ3CameraPlacement placement;
-
- assert(inPosition != NULL);
- assert(inDirection != NULL);
- assert(inUp != NULL);
-
- // Move the camera
- placement.cameraLocation = *inPosition;
- placement.upVector = *inUp;
-
- Q3Point3D_Vector3D_Add(inPosition, inDirection, &placement.pointOfInterest);
-
- Q3Camera_SetPlacement(gDisplayCamera, &placement);
-
- // Move the point light
- Q3PointLight_SetLocation(gDisplayPointLight, inPosition);
- }
-
-
- /* =============================================================================
- * Display_GetViewerPosition (external)
- *
- * Returns the current camera position.
- * ========================================================================== */
- void Display_GetViewerPosition(
- TQ3Point3D* outPosition,
- TQ3Vector3D* outDirection,
- TQ3Vector3D* outUp)
- {
- TQ3CameraPlacement placement;
-
- assert(outPosition != NULL);
- assert(outDirection != NULL);
- assert(outUp != NULL);
-
- Q3Camera_GetPlacement(gDisplayCamera, &placement);
-
- *outPosition = placement.cameraLocation;
- *outUp = placement.upVector;
-
- Q3Point3D_Subtract(
- &placement.pointOfInterest,
- &placement.cameraLocation,
- outDirection);
- }
-
-
- /* =============================================================================
- * Display_GetImageArea (internal)
- *
- * Sets outArea to the area occupied by the 3D image part of the window.
- * ========================================================================== */
- void Display_GetImageArea(
- TQ3Area* outArea)
- {
- assert(outArea != NULL);
-
- #if USE_DRAW_SPROCKET
- {
- DisplayConfig theConfig;
-
- GetDisplayConfig( gDisplayObject, &theConfig );
-
- outArea->min.x = 0;
- outArea->max.x = theConfig.width;
- outArea->min.y = 0;
- outArea->max.y = theConfig.height;
- }
- #else
- outArea->min.x = gDisplayWindow->portRect.left;
- outArea->max.x = gDisplayWindow->portRect.right;
- outArea->min.y = gDisplayWindow->portRect.top;
- outArea->max.y = gDisplayWindow->portRect.bottom-15;
- #endif
- }
-
-
- /* =============================================================================
- * Display_GetImageAspectRatio (internal)
- *
- * Returns the aspect ratio of the area occupied by the 3D image part of the
- * window.
- * ========================================================================== */
- float Display_GetImageAspectRatio(
- void)
- {
- TQ3Area imageArea;
-
- Display_GetImageArea(&imageArea);
-
- return (imageArea.max.x-imageArea.min.x) / (imageArea.max.y-imageArea.min.y);
- }
-